﻿using System;
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;

namespace DL.UI
{
    public static class PageMgr
    {
        public static Func<string, GameObject> PageLoader;
        private static Transform _uiParent;

        public static Transform UIParent
        {
            get
            {
                if (_uiParent == null)
                {
                    var go = GameObject.Find("UIParent");
                    if (go != null)
                    {
                        _uiParent = go.transform;
                    }
                }

                return _uiParent;
            }
            set { _uiParent = value; }
        }

        public static Camera UICam;



        // public static Transform TextTipParent;//从未赋值,单独做
        public static bool ShowLog = false;

        private static Dictionary<PageType, string> pageRootParentDic = new Dictionary<PageType, string>()
         {
             { PageType.BasePage, "BaseParent" },
             { PageType.PopPage, "PopParent" },
             { PageType.TipPage, "PopParent" },
             // { PageType.BubblePage, "PopParent" },
             // { PageType.SurfacePage, "SurfaceParent" },
             // { PageType.BlockPage, "BlockParent" }
         };

        public static Transform GetPageRootParent(PageType pageType)
        {
            if (pageRootParentDic.ContainsKey(pageType) && UIParent != null)
            {
                return UIParent.Find(pageRootParentDic[pageType]);
            }

            return UIParent;
        }

        private static AbstractPage Show(string pageName, PageType pageType, PageParam param)
        {
            var page = GetPage(pageName, pageType);
            if (page != null)
            {
                page.Show(pageName, pageType, param);
            }

            return page;
        }

        public static AbstractPage Hide(string pageName, bool withTween = true, bool eraseOnPathPoint = false)
        {
            var page = GetExistedPage(pageName);
            if (page != null)
            {
                if (withTween)
                {
                    page.Hide(eraseOnPathPoint);
                }
                else
                {
                    page.HideNow(eraseOnPathPoint);
                }
            }
            return page;
        }

        public static AbstractPage ShowBasePage(string pageName, PageParam param = null)
        {
            HideAllPopPage();
            if (PageCaches.Inst.CurrentPathPoint.basePageName != pageName)
            {
                Hide(PageCaches.Inst.CurrentPathPoint.basePageName);
            }

            var page = Show(pageName, PageType.BasePage, param);

            RecordPathPoint(pageName, PageType.BasePage);
            page.transform.SetAsFirstSibling();
            return page;
        }

        private static List<string> NonReturnBasePageNames = new List<string>() {};

        public static PagePathPoint ReturnPage()
        {
            var pathPoint = PageCaches.Inst.BackwardPathPoint();
            var pageName =
                string.IsNullOrEmpty(pathPoint.basePageName) || NonReturnBasePageNames.Contains(pathPoint.basePageName)
                    ? PagePathPoint.StartPageName
                    : pathPoint.basePageName;
            if (PageCaches.Inst.CurrentPathPoint.basePageName != pageName)
            {
                Hide(PageCaches.Inst.CurrentPathPoint.basePageName);
            }

            PageCaches.Inst.CurrentPathPoint = pathPoint;

            //BasePage
            var page = GetExistedPage(pageName); //这里的界面必然是之前展示过的
            if (page != null)
            {
                page.ShowByReturn();
            }

            page.transform.SetAsFirstSibling();
            //PopPages
            if (pathPoint.returnablePageNameRecord != null)
            {
                foreach (var popPageName in pathPoint.returnablePageNameRecord)
                {
                    var popPage = GetExistedPage(popPageName.PageName); //这里的界面必然是之前展示过的
                    if (popPage != null)
                    {
                        popPage.ShowByReturn();
                    }

                    popPage.transform.SetAsLastSibling();
                }
            }

            return pathPoint;
        }

        private static void RecordPathPoint(string pageName, PageType pageType)
        {
            if (pageType != PageType.BasePage && pageType != PageType.PopPage)
            {
                return;
            }

            if (pageName == PagePathPoint.StartPageName && PageCaches.Exist())
            {
                PageCaches.Inst.ClearPath();
                PageCaches.Inst.CurrentPathPoint.basePageName = pageName;
                PageCaches.Inst.CurrentPathPoint.ClearRecord();
                return;
            }

            switch (pageType)
            {
                case PageType.BasePage:
                    PageCaches.Inst.ForwardPathPoint(pageName);
                    break;
                case PageType.PopPage:
                    PageCaches.Inst.CurrentPathPoint.RecordPage(pageName, pageType);
                    break;
            }
        }

        public static AbstractPage ShowPopPage(string pageName, PageParam param = null)
        {
            var page = Show(pageName, PageType.PopPage, param);
            RecordPathPoint(pageName, PageType.PopPage);
            page.transform.SetAsLastSibling();
            return page;
        }

        public static AbstractPage ShowTipPage(string pageName, PageParam param = null)
        {
            var page = Show(pageName, PageType.TipPage, param);
            page.transform.SetAsLastSibling();
            return page;
        }

        public static AbstractPage ShowBlockPage(string pageName, PageParam param = null)
        {
            var page = Show(pageName, PageType.BlockPage, param);
            page.transform.SetAsLastSibling();
            return page;
        }

        public static AbstractPage ShowBubblePage(string pageName, PageParam param = null)
        {
            var page = Show(pageName, PageType.BubblePage, param);
            page.transform.SetAsLastSibling();
            return page;
        }

        public static AbstractPage ShowSurfacePage(string pageName, PageParam param = null)
        {
            var page = Show(pageName, PageType.SurfacePage, param);
            page.transform.SetAsLastSibling();
            return page;
        }

        public static AbstractPage ShowBaseTabPage(string parentPageName, string tabPageName, PageParam param = null)
        {
            return ShowBasePage(parentPageName, param).ShowTabPage(tabPageName, param);
        }


        public static AbstractPage ShowBaseTabPage(string parentPageName, string tabPageName1, string tabPageName2,
            PageParam param = null)
        {
            return ShowBasePage(parentPageName, param).ShowTabPage(tabPageName1, param)
                .ShowTabPage(tabPageName2, param);
        }


        public static AbstractPage ShowPopTabPage(string parentPageName, string tabPageName, PageParam param = null)
        {
            return ShowPopPage(parentPageName, param).ShowTabPage(tabPageName, param);
        }

        public static AbstractPage ShowTipTabPage(string parentPageName, string tabPageName, PageParam param = null)
        {
            return ShowTipPage(parentPageName, param).ShowTabPage(tabPageName, param);
        }

        public static AbstractPage ShowPopTabPage(string parentPageName, string tabPageName1, string tabPageName2,
            PageParam param = null)
        {
            return ShowPopPage(parentPageName, param).ShowTabPage(tabPageName1, param).ShowTabPage(tabPageName2, param);
        }

        public static AbstractPage ShowTipTabPage(string parentPageName, string tabPageName1, string tabPageName2,
            PageParam param = null)
        {
            return ShowTipPage(parentPageName, param).ShowTabPage(tabPageName1, param).ShowTabPage(tabPageName2, param);
        }

        public static AbstractPage GetExistedPage(string pageName)
        {
            if (!string.IsNullOrEmpty(pageName))
            {
                var page = PageCaches.Inst.GetPage(pageName);
                if (page != null)
                {
                    return page;
                }
            }

            return null;
        }

        public static AbstractPage GetPage(string pageName, PageType pageType, bool createIfNot = true)
        {
            if (!string.IsNullOrEmpty(pageName))
            {
                var page = PageCaches.Inst.GetPage(pageName);
                if (page != null)
                {
                    return page;
                }

                if (createIfNot)
                {
                    if (PageLoader != null)
                    {
                        // todo 接入YooAsset
                        // var prefab = PageLoader(AssetInfo._paths["Page"] + pageName);
                        var prefab = PageLoader(pageName);

                        if (prefab != null)
                        {
                            var go = Object.Instantiate(prefab, GetPageRootParent(pageType));
                            if (go != null)
                            {
                                go.name = pageName;
                                page = go.GetComponent<AbstractPage>();
                                if (page != null)
                                {
                                    PageCaches.Inst.Add(pageName, page);
                                    return page;
                                }
                            }
                        }
                    }
                }
            }

            return null;
        }

        public static AbstractPage GetTabPage(string pageName, Transform parentTransform, bool createIfNot = true)
        {
            if (!string.IsNullOrEmpty(pageName))
            {
                var page = PageCaches.Inst.GetPage(pageName);
                if (page != null)
                {
                    if (parentTransform != null)
                    {
                        page.transform.SetParent(parentTransform, false);
                    }

                    return page;
                }

                if (createIfNot)
                {
                    if (PageLoader != null)
                    {
                        var prefab = PageLoader(pageName);
                        if (prefab != null)
                        {
                            var go = Object.Instantiate(prefab, parentTransform);
                            if (go != null)
                            {
                                go.name = pageName;
                                page = go.GetComponent<AbstractPage>();
                                if (page != null)
                                {
                                    PageCaches.Inst.Add(pageName, page);
                                    return page;
                                }
                            }
                        }
                    }
                }
            }

            return null;
        }


        public static void PreLoadPage(string pageName)
        {
            var page = PageCaches.Inst.GetPage(pageName);
            if (page == null)
            {
                if (PageLoader != null)
                {
                    // todo 接入YooAsset
                    // var prefab = PageLoader(AssetInfo._paths["Page"] + pageName);
                    var prefab = PageLoader(pageName);

                    var go = Object.Instantiate(prefab, UIParent);
                    if (go != null)
                    {
                        go.name = pageName;
                        page = go.GetComponent<AbstractPage>();
                        if (page != null)
                        {
                            PageCaches.Inst.Add(pageName, page);
                        }

                        go.SetActive(false);
                    }
                }
            }
        }

        /// <summary>
        /// 查看指定界面是否处于激活状态
        /// </summary>
        public static bool IsPageActive(string pageName)
        {
            if (!string.IsNullOrEmpty(pageName))
            {
                var page = PageCaches.Inst.GetPage(pageName);
                if (page != null && page.gameObject.activeInHierarchy)
                {
                    return true;
                }
            }

            return false;
        }

        public static void HideAllPopPage(bool includeSurfacePage = false)
        {
            if (PageCaches.Exist())
            {
                PageCaches.Inst.HideAllPopPage();
                if (includeSurfacePage)
                {
                    PageCaches.Inst.HideAllSurfacePage(); //BubblePage的管理在BubbleManager中
                }
            }
        }

        public static void HideAllSurfacePage()
        {
            if (PageCaches.Exist())
            {
                PageCaches.Inst.HideAllSurfacePage();
            }
        }

        public static void ClearCurrentPagePathPointRecord()
        {
            if (PageCaches.Exist())
            {
                PageCaches.Inst.CurrentPathPoint.ClearRecord();
            }
        }

        public static void ClearAllPagePath()
        {
            if (PageCaches.Exist())
            {
                PageCaches.Inst.ClearPath();
            }
        }

        public static bool AnyPopPageOn()
        {
            if (PageCaches.Exist())
            {
                return PageCaches.Inst.AnyPopPageOn();
            }

            return false;
        }
    }
}